<?php
/**
 * (海外仓-谷仓)（海外仓配-入库单）
 */

namespace App\Logic\Plat\Rakuten\Overseas\GuCang\InboundOrder;


use App\Logic\Plat\Rakuten\Overseas\GuCang\RakutenOverseasClient;
use App\Models\Basics\ExpressChannel;
use App\Models\OverSeasBa\DropshippingInventoryFnsku;
use App\Models\OverSeasIn\Delivery;
use App\Models\OverSeasIn\DeliveryBox;
use App\Models\OverSeasIn\DeliveryBoxDetail;
use App\Models\OverSeasIn\DeliveryLogistics;
use App\Models\Rakuten\RakutenLogs;

class OverseasInboundOrder extends RakutenOverseasClient{

    const get_grn_list = 'public_open/inbound_order/get_grn_list'; //获取入库单列表
    const get_grn_detail = 'public_open/inbound_order/get_grn_detail'; //入库单明细
    const create_grn = 'public_open/inbound_order/create_grn'; //创建入库单
    const modify_grn = 'public_open/inbound_order/modify_grn'; //更新入库单
    const del_grn = 'public_open/inbound_order/del_grn'; //废弃(删除)入库单


    /**
     * 入库单列表
     * @param array $receivingIds
     * @return array
     */
    public static function getGrnList($receivingIds = []){
        $apiParams = [
            //'modify_date_from' => date('Y-m-d H:i:s', strtotime('2024-06-01 00:00:00')), //开始时间
            'modify_date_from' => date('Y-m-d H:i:s', strtotime("-7 days")), //开始时间
            'modify_date_to' => date('Y-m-d H:i:s', time()),//结束时间
            'receiving_code_arr' => $receivingIds, //入库单号
            'code_type' => 1, //单号类型(1:谷仓入库单号 2:参考单号(erp发货单号))
            'page' => 1,
            'pageSize' => 100
        ];

        $res = self::getRequest(self::get_grn_list,$apiParams);
        if ($res) {
            if ($res->message == 'Success') {
                //谷仓的所有入库单 (分页数据,合并)
                return self::getResultList($res,self::get_grn_list,$apiParams);
            }else{
                //日志
                RakutenLogs::logs(RakutenLogs::$overseasInboundOrder,
                    json_encode($res,JSON_UNESCAPED_UNICODE),
                    json_encode($apiParams,JSON_UNESCAPED_UNICODE)
                );
                return [];
            }
        }
    }

    /**
     * 入库单明细
     * @param $receivingIds
     * @return mixed
     */
    public static function getGrnDetail($receivingIds = []){

        //海外入库单
        $receivingData = self::getGrnList($receivingIds);
        if (!$receivingData) return false;

        $flag = false;
        foreach ($receivingData as $receiving){
            if ($receiving->receiving_status != 10) continue; //海外仓入库单状态 (0:草稿 9:海外仓收货完成 10:海外上架完成 100:废弃)
            $deliveryNo = $receiving->reference_no; //erp发货单号
            $receivingCode = $receiving->receiving_code; //erp批次号
            $trackingNumber = $receiving->tracking_number ?? ''; //erp物流追踪号

            //验证：国内发货单
            $delivery = Delivery::query()
                //->where('delivery_no',$deliveryNo)
                ->where('batch_no',$receivingCode)
                ->where('status',6) //已发货
                ->first();
            if (!$delivery) continue;

            //验证：国内发货单装箱信息(是否已完成入库)
            $deliveryStatus = DeliveryBox::query()
                //->where('delivery_no',$deliveryNo)
                ->where('batch_no',$receivingCode)
                ->min('status');
            if (!$deliveryStatus) continue;
            if ($deliveryStatus == 3) continue; //国内erp发货单入库状态 (1:待入库 2:部分入库 3:已入库)

            //海外入库单明细
            $apiParams = [
                'receiving_code' => $receiving->receiving_code, //海外仓入库单号
                'page' => 1,
                'pageSize' => 100
            ];
            $res = self::getRequest(self::get_grn_detail,$apiParams);
            if ($res->message == 'Success') {
                if (!$res->data) continue;
                if (!$res->data->overseas_detail) continue;

                $dealAt = $res->data->gc_putaway_time ?? date('Y-m-d H:i:s'); //erp入库时间(海外仓上架时间)
                foreach ($res->data->overseas_detail as $key => $val){
                    //装箱信息
                    $deliveryBox = DeliveryBox::query()
                        ->where([
                            //'delivery_no' => $deliveryNo,
                            'batch_no' => $receivingCode,
                            'box_no' => $val->box_no,
                            'fnsku' => $val->product_sku,
                            'delivery_type' => 2, //发货单类型 （1=>中转，2=>代发）
                            'status' => 1 //入库状态 （1：待入库 2：部分入库 3：完全入库）
                        ])->first();
                    if ($deliveryBox) {
                        if ($val->overseas_shelves_count < $deliveryBox->num_per_box) continue;
                        $overseasTotal = intval($val->overseas_shelves_count / $deliveryBox->num_per_box); //海外仓箱数
                        $total = $deliveryBox->total; //总箱数
                        $storageTotal = $deliveryBox->storage_total; //已入库箱数
                        $thisStorageTotal = min($total - $storageTotal,$overseasTotal); //当前入库箱数
                        $deliveryBox->storage_total += $thisStorageTotal;
                        if($deliveryBox->storage_total > 0){
                            if($total == $deliveryBox->storage_total){
                                $deliveryBox->status = 3; //完全入库
                            }else{
                                $deliveryBox->status = 2; //部分入库
                            }
                        }
                        $deliveryBox->save();

                        //更新装箱明细
                        DeliveryBoxDetail::_upBoxDetail($deliveryBox->id,$total,$storageTotal,$thisStorageTotal,$dealAt,DeliveryBoxDetail::INBOUND_YES);

                        //更新库存FnSku数量 (海外仓&一件代发库存)
                        $num = intval($thisStorageTotal * $deliveryBox->num_per_box);
                        DropshippingInventoryFnsku::_upInventoryBoxFnSku($deliveryBox->warehouse_id,$deliveryBox->account_id,$deliveryBox->fnsku,$deliveryBox->psku_id,$num,$deliveryBox->plat_id);
                    }
                }

                //更新发货单物流
                DeliveryLogistics::query()->updateOrCreate([
                    'delivery_no' => $delivery->delivery_no
                ], [
                    'arrived_at' => $dealAt,
                    'tracking_no' => $trackingNumber
                ]);

                $flag = true;
            }else{
                //日志
                RakutenLogs::logs(RakutenLogs::$overseasOrderShippingMethod,
                    json_encode($res,JSON_UNESCAPED_UNICODE),
                    json_encode($apiParams,JSON_UNESCAPED_UNICODE)
                );
                $flag = false;
            }
        }

        return $flag;
    }

    /**
     * 创建入库单
     * @param $deliveryNo
     * @return mixed
     */
    public static function createGrn($deliveryNo){
        $delivery = Delivery::query()->where('delivery_no',$deliveryNo)->first();
        if(!$delivery) return false;
        if(!$delivery->detail) return false;
        if(!$delivery->logistics) return false;

        //运输方式
        $expressChannel = ExpressChannel::getModel($delivery->logistics->express_channel_id);
        if(!$expressChannel) return false;
        $receivingShippingType = ExpressChannel::$os_transport[$expressChannel->transport];

        $itemsArr = [];
        foreach ($delivery->box as $key => $val){
            $itemsArr[$val->box_no]['box_no'] = $val->box_no;
            $itemsArr[$val->box_no]['box_details'][] = [
                'product_sku' => $val->fnsku,
                'quantity' => intval($val->total * $val->num_per_box) ?? 0 //数量 = (发货总箱数 * 箱规格数量)
            ];
        }

        $apiParams = [
            'transit_type' => 0, //Int *入库单类型(0:标准(自发)入库单 3:中转入库单(标准货运单) 5:FBA/计划单入库单)
            'reference_no' => $delivery->delivery_no, //String(50) 参考号
            'receiving_shipping_type' => $receivingShippingType, //Int *运输方式(0:空运 1:海运散货 2:快递 3:铁运整柜 4:海运整柜 5:铁运散货)
            'warehouse_code' => self::WAREHOUSE_CODE, //String(32) *海外仓仓库编码
            'wp_code' => self::WP_CODE, //String 物理仓仓库代码
            'tracking_number' => $delivery->logistics->tracking_no ?? '', //String(35) 跟踪号/海柜号
            'eta_date' => $delivery->logistics->arrived_at, //Datetime 预计到达时间（格式：YYYY-MM-DD）。自发入库单和FBA/计划入库单必填
            'items' => $itemsArr, //Object[] 入库单明细
            'receiving_desc' => $delivery->remarks ?? '', //String(255) 备注
            'verify' => 0, //Int 是否审核 (0:新建不审核(草稿状态) 1:新建并审核)
            'page' => 1,
            'pageSize' => 10
        ];

        $res = RakutenOverseasClient::getRequest(self::create_grn,$apiParams);
        if ($res->message == 'Success') {
            $receivingCode = $res->data->receiving_code ?? '';
            //更新批次号
            $delivery->batch_no = $receivingCode;
            $delivery->save();

            DeliveryBox::query()
                ->where('delivery_no', $delivery->delivery_no)
                ->update([
                    'batch_no' => $receivingCode
                ]);
            return true;
        }else{
            //日志
            RakutenLogs::logs(RakutenLogs::$overseasInboundOrder,
                json_encode($res,JSON_UNESCAPED_UNICODE),
                json_encode($apiParams,JSON_UNESCAPED_UNICODE)
            );
            return false;
        }

        //$apiParams = [
        //    'transit_type' => 0, //Int *入库单类型(0:标准(自发)入库单 3:中转入库单(标准货运单) 5:FBA/计划单入库单)
        //    'reference_no' => $delivery->delivery_no, //String(50) 参考号
        //    'receiving_shipping_type' => 1, //Int *运输方式(0:空运 1:海运散货 2:快递 3:铁运整柜 4:海运整柜 5:铁运散货)
        //    'tracking_number' => 'aaa', //String(35) 跟踪号/海柜号
        //
        //    'warehouse_code' => self::WAREHOUSE_CODE, //String(32) *海外仓仓库编码
        //    'eta_date' => ' 2024-07-26', //Datetime 预计到达时间（格式：YYYY-MM-DD）。自发入库单和FBA/计划入库单必填
        //    'verify' => 0, //Int 是否审核值(0:新建不审核(草稿状态) 1:新建并审核)
        //    'receiving_desc' => 'test', //String(255) 备注
        //    'shiper_address' => [
        //        'sa_contacter' => 'lucy', //String(50) *联系人
        //        'sa_contact_phone' => '18500000000', //String(50) *联系电话（手机号）
        //        'sa_country_code' => 'CN', //String(2) *发件国家/地区简称
        //        'sa_state' => '广东省', //String(50) *省/州
        //        'sa_city' => '深圳市', //String(50) *城市
        //        'sa_region' => '龙岗区', //String(50) 区
        //        'sa_address1' => '创汇国际', //String(50) 地址1
        //        'sa_address2' => '' //String(50) 地址2
        //    ], //Object 入库单发货地址(仅适用于自发入库单)
        //    'items' => [
        //        [
        //            'reference_box_no' => 'a11', //String(30) 箱唛参考号,自发入库单或FBA/计划单入库单才有该字段,FBA/计划单入库单，且为仓库装箱商品（is_rollover=1）时，必填。
        //            'box_no' => 1, //Int *必填箱号
        //            'box_details' => [
        //                [
        //                    'product_sku' => 'AM02374', //String(24) *商品SKU
        //                    'quantity' => 10, //Int *数量
        //                    'fba_product_code' => '',
        //                    'data_code' => '',
        //                    'serial_number' => ''
        //                ],
        //                [
        //                    'product_sku' => 'AM02375', //String(24) *商品SKU
        //                    'quantity' => 10, //Int *数量
        //                    'fba_product_code' => '',
        //                    'data_code' => '',
        //                    'serial_number' => ''
        //                ]
        //            ], //Object[] 箱子信息
        //        ],
        //        [
        //            'reference_box_no' => 'a22', //String(30) 箱唛参考号,自发入库单或FBA/计划单入库单才有该字段,FBA/计划单入库单，且为仓库装箱商品（is_rollover=1）时，必填。
        //            'box_no' => 2, //Int *必填箱号
        //            'box_details' => [
        //                [
        //                    'product_sku' => 'AM02374', //String(24) *商品SKU
        //                    'quantity' => 20, //Int *数量
        //                    'fba_product_code' => '',
        //                    'data_code' => '',
        //                    'serial_number' => ''
        //                ],
        //                [
        //                    'product_sku' => 'AM02375', //String(24) *商品SKU
        //                    'quantity' => 20, //Int *数量
        //                    'fba_product_code' => '',
        //                    'data_code' => '',
        //                    'serial_number' => ''
        //                ]
        //            ], //Object[] 箱子信息
        //        ]
        //    ], //Object[] 入库单明细
        //    'wp_code' => '', //String 物理仓仓库代码
        //
        //    'page' => 1,
        //    'pageSize' => 10
        //];
    }

    /**
     * 更新入库单
     * @param $deliveryNo
     * @return mixed
     */
    public static function modifyGrn($deliveryNo){

        $delivery = Delivery::query()->where('delivery_no',$deliveryNo)->first();
        if(!$delivery) return false;
        if(!$delivery->detail) return false;
        if(!$delivery->logistics) return false;


        $itemsArr = [];
        foreach ($delivery->box as $key => $val){
            $itemsArr[$val->box_no]['box_no'] = $val->box_no;
            $itemsArr[$val->box_no]['box_details'][] = [
                'product_sku' => $val->fnsku,
                'quantity' => intval($val->total * $val->num_per_box) ?? 0 //数量 = (发货总箱数 * 箱规格数量)
            ];
        }

        $apiParams = [
            'transit_type' => 0, //Int *入库单类型(0:标准(自发)入库单 3:中转入库单(标准货运单) 5:FBA/计划单入库单)
            'reference_no' => $delivery->delivery_no, //String(50) 参考号
            'receiving_shipping_type' => 1, //Int *运输方式(0:空运 1:海运散货 2:快递 3:铁运整柜 4:海运整柜 5:铁运散货)
            'warehouse_code' => self::WAREHOUSE_CODE, //String(32) *海外仓仓库编码
            'wp_code' => self::WP_CODE, //String 物理仓仓库代码
            'tracking_number' => $delivery->logistics->tracking_no, //String(35) 跟踪号/海柜号
            'eta_date' => $delivery->logistics->arrived_at, //Datetime 预计到达时间（格式：YYYY-MM-DD）。自发入库单和FBA/计划入库单必填
            'items' => $itemsArr, //Object[] 入库单明细
            'receiving_desc' => $delivery->remarks, //String(255) 备注

            'page' => 1,
            'pageSize' => 10
        ];

        $res = RakutenOverseasClient::getRequest(self::modify_grn,$apiParams);
        if ($res->message == 'Success') {
            return $res;
        }else{
            //日志
            RakutenLogs::logs(RakutenLogs::$overseasInboundOrder,
                json_encode($res,JSON_UNESCAPED_UNICODE),
                json_encode($apiParams,JSON_UNESCAPED_UNICODE)
            );
        }
    }

    /**
     * 删除入库单
     * @param $batchNo
     * @return mixed
     */
    public static function delGrn($batchNo){
        $apiParams = [
            'receiving_code' => $batchNo, //入库单号
        ];

        $res = self::getRequest(self::del_grn,$apiParams);
        if ($res->message == 'Success') {
            return $res;
        }else{
            //日志
            RakutenLogs::logs(RakutenLogs::$overseasInboundOrder,
                json_encode($res,JSON_UNESCAPED_UNICODE),
                json_encode($apiParams,JSON_UNESCAPED_UNICODE)
            );
        }
    }

}
